package ee.siimoliver.chat.GUI.dialogs;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.HashMap;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import net.miginfocom.swing.MigLayout;
import ee.siimoliver.chat.GUI.ChatFrame;
import ee.siimoliver.chat.GUI.LoadingFrame;
import ee.siimoliver.chat.controllers.BusinessLogicController;
import ee.siimoliver.chat.controllers.ChatSessionController;
import ee.siimoliver.chat.controllers.DialogController;
import ee.siimoliver.chat.utils.ApplicationProperties;
import ee.siimoliver.chat.utils.ChatUtils;
import ee.siimoliver.chat.utils.Const;
import ee.siimoliver.chat.utils.JsonParser;

public class NewChatDialog extends JDialog implements Const, DialogController {

	private static final long serialVersionUID = 1L;
	private final int maxHeight = 600;
	private JScrollPane scrollPane;
	private JPanel usersList;
	private JButton btnNew;
	private JButton btnCancel;
	private JButton btnRefreshAll;
	private JLabel lblInfo;
	private BusinessLogicController businessController;
	private ChatSessionController chatSessionController;
	private String buttonText;

	public NewChatDialog(JFrame parent, BusinessLogicController businessController, String buttonText) {
		super(parent);
		parent.setEnabled(false);
		this.businessController = businessController;
		this.buttonText = buttonText;
		initFields();
		addProperties();
		addFields();
		pack();
		setDialogSize();
		ChatUtils.centerWindowRelativeToParent(this, parent);
	}
	
	public NewChatDialog(JFrame parent, BusinessLogicController controller, String buttonText,
			ChatSessionController chatSessionController) {
		this(parent, controller, buttonText);
		this.chatSessionController = chatSessionController;
	}
	
	private void setDialogSize() {
		Dimension dim = getSize();
		if (dim.getHeight() > maxHeight) {
			setSize(new Dimension((int) dim.getWidth() + 40, maxHeight));
		}

	}
	
	private void initFields() {
		usersList = new JPanel(new MigLayout("", "[grow, fill]", ""));
		scrollPane = new JScrollPane(usersList);
		btnNew = new JButton(LBL_NEW);
		btnCancel = new JButton(LBL_CANCEL);
		btnRefreshAll = new JButton(LBL_REFRESH_ALL);
		lblInfo = new JLabel(LBL_USERS_INFO);
	}
	
	private void addProperties() {
		setUndecorated(true);
		setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		((JPanel) getContentPane()).setBorder(BorderFactory.createLineBorder(Color.BLACK));
		btnCancel.addActionListener(new CancelAction());
		btnNew.addActionListener(new NewAction());
		btnRefreshAll.addActionListener(new RefreshAllAction());
	}
	
	private void addFields() {
		setLayout(new MigLayout("", "[grow, fill]", ""));
		addUsersMapButtons();
		add(lblInfo, "wrap");
		add(scrollPane, "span 4 1, wrap");
		add(btnRefreshAll, "cell 0 2, r");
		add(btnNew, "cell 1 2, r");
		add(btnCancel, "cell 2 2, r");
	}
	
	public void addUsersMapButtons() {
		try {
			usersList.removeAll();
			HashMap<String, String> users = JsonParser.readFile(
					String.format(USERS_TABLE_FILE, 
							ApplicationProperties.getInstance().getProperty(Const.PROP_USERNAME)));
			for (String key : users.keySet()) {
				JPanel panel = new JPanel(new MigLayout("", "[grow]20[]20[]", ""));
				panel.add(new JLabel(key));
				panel.add(new JLabel(users.get(key)));
				JButton btnAdd = new JButton(buttonText);
				panel.add(btnAdd, "r");
				btnAdd.addActionListener(new AddAction(key, users.get(key)));
				usersList.add(panel, "wrap");
			}
			pack();
			setDialogSize();
			validate();
			repaint();
		} catch (IOException e) {
			JOptionPane.showMessageDialog(this, e.getMessage(), TXT_ERROR, JOptionPane.ERROR_MESSAGE);
		}
	}
	
	public void display() {
		setVisible(true);
	}
	
	private void endDialog() {
		getParent().setEnabled(true);
		getParent().setVisible(true);
		this.dispose();
	}
	
	private class CancelAction implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			endDialog();
		}
	}
	
	private class NewAction implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent e) {
			ChattableInputDialog cid = new ChattableInputDialog(NewChatDialog.this, 
					(ChatFrame) NewChatDialog.this.getParent() , LBL_ENTER_NAME, ICON_SEARCH);
			cid.display();
		}
	}
	
	private class AddAction implements ActionListener {
		private String name;
		private String ipPort;
		public AddAction(String name, String ipPort) {
			this.name = name;
			this.ipPort = ipPort;
		}
		@Override
		public void actionPerformed(ActionEvent e) {
			if (businessController != null) {
				if (chatSessionController == null) {
					businessController.startNewChatSession(name, ipPort);
				} else {
					chatSessionController.addChatmate(name, ipPort);
				}
				if (chatSessionController != null) {
					chatSessionController.getOutputController().updatePanel();
				}
			}
			endDialog();
		}
	}
	private class RefreshAllAction implements ActionListener {
		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (businessController != null) {
				LoadingFrame lf = new LoadingFrame(((ChatFrame) getParent()).getLoadingImages(),
						NewChatDialog.this) {
					private static final long serialVersionUID = 1L;
					@Override
					protected void doInBackground() {
						try {
							businessController.searchChatmates(this);
							updateContent();
						} catch (Exception e) {
							JOptionPane.showMessageDialog(this,
									e.getMessage(), TXT_ERROR,
									JOptionPane.ERROR_MESSAGE);
						}
					}
				};
				lf.execute();
			}
		}
	}

	@Override
	public void updateContent() {
		addUsersMapButtons();
	}
}
